<?php
/**
 * Created by PhpStorm.
 * User: pc
 * Date: 2018/12/28
 * Time: 21:30
 */

namespace app\admin\controller;

use think\Db;

class Getamazonorders extends Main
{
    public $rate = [];

    /**
     *获取亚马逊订单信息
     */
    public function amazon()
    {
        $start = strtotime(post('start'));

        $end = (post('end') == '' || strtotime(post('end')) > time()) ? strtotime("-1 day") : strtotime(post('end'));
        if ($start >= $end) {
            $this->error("开始时间必须小于结束时间");
        }
        //获取当前汇率
        $this->rate = $this->getRate();
        //获取店铺信息
        $store = DB::name('amazon_store')->where('id', post('shop_id'))->find();
        $params = array(
            'AWSAccessKeyId' => $store['aws_access_key'],
            'Action' => "ListOrders",
            'SellerId' => $store['seller_id'],
            'SignatureMethod' => "HmacSHA256",
            'SignatureVersion' => "2",
            'Timestamp' => gmdate("Y-m-d\TH:i:s\Z", time()),
            'Version' => "2013-09-01",
            'CreatedAfter' => gmdate("Y-m-d\TH:i:s\Z", $start),
            'CreatedBefore' => gmdate("Y-m-d\TH:i:s\Z", $end),
            'MarketplaceId.Id.1' => $store['marketplace']
        );
        $url_parts = array();
        foreach (array_keys($params) as $key) {
            $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key]));
        }

        sort($url_parts);
        $url_string = implode("&", $url_parts);
        $string_to_sign = "GET\nmws.amazonservices.in\n/Orders/2013-09-01\n" . $url_string;

        $signature = hash_hmac("sha256", $string_to_sign, $store['secret_key'], TRUE);

        $signature = urlencode(base64_encode($signature));

        $url = "https://mws.amazonservices.in/Orders/2013-09-01" . '?' . $url_string . "&Signature=" . $signature;
        $content = request_get($url);
        if ($content == '') {
            $this->error('获取超时，请重试');
        }
        //获取订单列表
        $orders = xmlToArray($content);
        if (isset($orders['ListOrdersResult']['Orders']) && count($orders['ListOrdersResult']['Orders']) > 0) {
            //订单列表入库
            $nation = arrayCombine($this->getDictionary('nation'), 'short');
            $insertData = [];
            $orders = isset($orders['ListOrdersResult']['Orders']['Order'][0]) ? $orders['ListOrdersResult']['Orders']['Order'] : $orders['ListOrdersResult']['Orders'];
            foreach ($orders as $key => $value) {
                $insert = $this->insertOrder($value, $store, $nation);
                checkArr($insert) && $insertData[] = $insert;
            }
            checkArr($insertData) && Db::name('amazon_order')->insertAll($insertData);
            //存在下一页
            if (isset($orders['ListOrdersResult']['NextToken'])) {
                $this->insertNextOrders($orders['ListOrdersResult']['NextToken'], $store, $nation);
            }
        }
        $this->success("获取成功");
    }

    /**
     * 获取订单下一页列表数据
     * @param $nextToken
     * @param $store
     * @param $nation
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function insertNextOrders($nextToken, $store, $nation)
    {
        $params = array(
            'AWSAccessKeyId' => $store['aws_access_key'],
            'Action' => "ListOrdersByNextToken",
            'SellerId' => $store['seller_id'],
            'SignatureMethod' => "HmacSHA256",
            'SignatureVersion' => "2",
            'Timestamp' => gmdate("Y-m-d\TH:i:s\Z", time()),
            'Version' => "2013-09-01",
            'NextToken' => $nextToken
        );
        $url_parts = array();
        foreach (array_keys($params) as $key) {
            $url_parts[] = $key . "=" . str_replace('%7E', '~', rawurlencode($params[$key]));
        }


        sort($url_parts);

        $url_string = implode("&", $url_parts);
        $string_to_sign = "GET\nmws.amazonservices.in\n/Orders/2013-09-01\n" . $url_string;

        $signature = hash_hmac("sha256", $string_to_sign, $store['secret_key'], TRUE);

        $signature = urlencode(base64_encode($signature));

        $url = "https://mws.amazonservices.in/Orders/2013-09-01" . '?' . $url_string . "&Signature=" . $signature;

        $content = request_get($url);
        if ($content == '') {
            $this->error('获取超时，请重试');
        }
        //获取订单列表
        $orders = xmlToArray($content);
        if (isset($orders['ListOrdersByNextTokenResult']['Orders'])) {
            $orders = isset($orders['ListOrdersByNextTokenResult']['Orders']['Order'][0]) ? $orders['ListOrdersByNextTokenResult']['Orders']['Order'] : $orders['ListOrdersResult']['Orders'];
            foreach ($orders as $key => $value) {
                $insertData[] = $this->insertOrder($value, $store, $nation);
            }
            Db::name('amazon_order')->insertAll($insertData);
            //存在下一页
            if (isset($orders['ListOrdersByNextTokenResult']['NextToken'])) {
                $this->insertNextOrders($orders['ListOrdersByNextTokenResult']['NextToken'], $store, $nation);
            }
        }
        return true;
    }

    /**
     * 订单列表入库
     * @param $data
     * @param $store
     * @param $nation
     * @return mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function insertOrder($data, $store, $nation)
    {
        $insertData['order_no'] = $data['AmazonOrderId'];
        $num = Db::name('amazon_order')->where('order_no', $data['AmazonOrderId'])->find();
        if (checkArr($num) > 0) {
            return false;
        }
        if ($data['OrderStatus'] == 'Canceled') {
            return false;
        }
        $insertData['shipping_type'] = $data['FulfillmentChannel'];
        $insertData['user_name'] = isset($data['ShippingAddress']['Name']) ? $data['ShippingAddress']['Name'] : '';
        $insertData['pay_time'] = gmtToUtc($data['PurchaseDate']);
        $insertData['receiver_phone'] = isset($data['ShippingAddress']['Phone']) ? $data['ShippingAddress']['Phone'] : '';
        $insertData['receive_nation_id'] = isset($nation[$data['ShippingAddress']['CountryCode']]['id']) ? $nation[$data['ShippingAddress']['CountryCode']]['id'] : '';
        $insertData['receive_nation_short'] = isset($data['ShippingAddress']['CountryCode']) ? $data['ShippingAddress']['CountryCode'] : '';
        $insertData['receive_nation'] = isset($nation[$data['ShippingAddress']['CountryCode']]['name']) ? $nation[$data['ShippingAddress']['CountryCode']]['name'] : $store['nation'];
        $insertData['receiver_province'] = isset($data['ShippingAddress']['StateOrRegion']) ? $data['ShippingAddress']['StateOrRegion'] : '';
        $insertData['receiver_city'] = isset($data['ShippingAddress']['City']) ? $data['ShippingAddress']['City'] : '';
        $insertData['receiver_district'] = isset($data['ShippingAddress']['County']) ? $data['ShippingAddress']['County'] : '';
        $address = isset($data['ShippingAddress']['AddressLine1']) ? $data['ShippingAddress']['AddressLine1'] : '';
        isset($data['ShippingAddress']['AddressLine2']) && $address .= $data['ShippingAddress']['AddressLine2'];
        isset($data['ShippingAddress']['AddressLine3']) && $address .= $data['ShippingAddress']['AddressLine3'];
        $insertData['receiver_address'] = $address;
        $insertData['receiver_zip'] = isset($data['ShippingAddress']['PostalCode']) ? $data['ShippingAddress']['PostalCode'] : '';
        $insertData['receiver_name'] = isset($data['ShippingAddress']['Name']) ? $data['ShippingAddress']['Name'] : '';
        $insertData['receiver_email'] = isset($data['BuyerEmail']) ? $data['BuyerEmail'] : '';
        $insertData['shop_id'] = $store['id'];
        $insertData['shop_name'] = $store['name'];
        $insertData['earliest_ship_time'] = isset($data['EarliestShipDate']) ? gmtToUtc($data['EarliestShipDate']) : '';
        $insertData['latest_ship_time'] = isset($data['LatestShipDate']) ? gmtToUtc($data['LatestShipDate']) : '';
        $insertData['order_total'] = isset($data['OrderTotal']['Amount']) ? $this->toCny($data['OrderTotal']['Amount'], $data['OrderTotal']['CurrencyCode']) : 0;
        $insertData['profit'] = $insertData['order_total'];
        $insertData['order_money'] = isset($data['OrderTotal']['Amount']) ? $data['OrderTotal']['Amount'] : 0;
        $insertData['pay_money'] = isset($data['OrderTotal']['Amount']) ? $data['OrderTotal']['Amount'] : 0;
        switch ($data['OrderStatus']) {
            case "PendingAvailability":
                $order_status = 1;
                break;
            case "Pending":
                $order_status = 1;
                break;
            case "Unshipped":
                $order_status = 7;
                break;
            case "PartiallyShipped":
                $order_status = 8;
                break;
            case "Shipped":
                $order_status = 8;
                break;
            case "InvoiceUnconfirmed":
                $order_status = 9;
                break;
            case "Canceled":
                $order_status = 2;
                break;
            case "Unfulfillable":
                $order_status = 6;
                break;
            default:
                $order_status = 3;
                break;
        }
        $insertData['order_status'] = $order_status;
        $insertData['pay_status'] = $order_status;
//        $insertData['shipping_status'] = $order_status;
        $insertData['create_time'] = gmtToUtc($data['PurchaseDate']);
        $insertData['coin'] = isset($data['OrderTotal']['CurrencyCode']) ? $data['OrderTotal']['CurrencyCode'] : '';
        $insertData['delivery_time'] = intval(floor(($insertData['latest_ship_time'] - $insertData['earliest_ship_time']) / 2)) + $insertData['earliest_ship_time'];
        $insertData['last_time'] = isset($data['EarliestDeliveryDate']) ? gmtToUtc($data['EarliestDeliveryDate']) : '';
        $insertData['updatetime'] = gmtToUtc($data['LastUpdateDate']);
        $insertData['rate'] = isset($data['OrderTotal']['CurrencyCode']) ? $this->rate[$data['OrderTotal']['CurrencyCode']]['rate'] : 0;
        $insertData['delivery'] = isset($data['NumberOfItemsShipped']) ? $data['NumberOfItemsShipped'] : 0;
        $insertData['delivery_no'] = isset($data['NumberOfItemsUnshipped']) ? $data['NumberOfItemsUnshipped'] : 0;
        $insertData['goods_num'] = $insertData['delivery'] + $insertData['delivery_no'];
        $insertData['company_id'] = isession('company_id');
        return $insertData;
    }

    /**
     * 外汇换算人民币
     * @param int $money
     * @param string $unit
     * @return float|int
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public function toCny($money = 0, $unit = '')
    {
        if ($money == 0 || $unit == '') {
            return 0;
        }

        //存在汇率
        if (isset($this->rate[$unit])) {
            return $money / ($this->rate[$unit]['rate']);
        }
        //获取汇率
        $this->rate[$unit] = $this->getCNY($unit, 'insert', 1);
        return $money / $this->rate[$unit]['rate'];
    }

}